package com.AUI.components
{
	import com.AUI.events.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	/**
	 * Oneway container,is oneway alignment.
	 * <p>Its elements are either horizontal aligned or vertical aligned.</p>
	 * @author HuangMinPing
	 * @site www.AminLab.com
	 */
	public class OnewayContainer extends Container
	{
		/**
		 * Configuration.
		 */
		private var _config:CONFIG = new CONFIG;
		/**
		 * [cache] The gap of elements of the component.
		 */
		private var _gap:int = 0;
		/**
		 * Constructor.
		 */
		public function OnewayContainer(horizontal:Boolean)
		{
			// init attributes
			if(horizontal)
			{
				_config.X = 'x';
				_config.W = 'width';
				_config.Y = 'y';
				_config.HD = 'h';
			}
			else
			{
				_config.X = 'y';
				_config.W = 'height';
				_config.Y = 'x';
				_config.HD = 'v';
			}
			// init elements
			elements.addEventListener(MouseEvent.CLICK,onClickElements,false,0,true);
			
			
			/**************** INITCOMPLETE ****************/
			Object(this).constructor == OnewayContainer && initComplete();
		}
		
		/**
		 * Called when MouseEvent.CLICK event has been dispatched on the elements of component.
		 * @see com.AUI.ABoxModel#elements
		 */
		protected function onClickElements(e:MouseEvent):void
		{
			var item:DisplayObject = DisplayObject(e.target);
			while(item.parent != elements)
			{
				item = item.parent;
			}
			var event:AItemEvent = new AItemEvent(AItemEvent.CLICK);
			event.index = elements.getChildIndex(item);
			event.item  = item;
			this.dispatchEvent(event);
		}
		/**
		 * @private
		 */
		override public function addElementAt(element:DisplayObject,index:int):DisplayObject
		{
			var X:String = _config.X;
			var W:String = _config.W;
			var Y:String = _config.Y;
			var num:int = numElements;
			// first position
			if(num == 0)
			{
				element[X] = 0;
				element[Y] = 0;
				elements.addChildAt(element,index);
			}
			// last position
			else if(num == index)
			{
				var lastElement:DisplayObject = elements.getChildAt(index - 1);
				element[X] = lastElement[X] + lastElement[W] + _gap;
				element[Y] = 0;
				elements.addChildAt(element,index);
			}
			// other position
			else
			{
				elements.addChildAt(element,index);
				updateAlignment(index);
			}
			// update content box
			updateContentBox();
			return element;
		}
		/**
		 * @private
		 */
		override public function removeElementAt(index:int):DisplayObject
		{
			var element:DisplayObject;
			var num:int = numElements;
			// first or last position
			if(num == index)
			{
				element = elements.removeChildAt(index);
			}
			else
			{
				element = elements.removeChildAt(index);
				updateAlignment(index);
			}
			updateContentBox();
			return element;
		}
		/**
		 * @private
		 */
		override public function replaceElementAt(element:DisplayObject,index:int):DisplayObject
		{
			var removeElement:DisplayObject = elements.removeChildAt(index);
			elements.addChildAt(element,index);
			updateAlignment(index);
			updateContentBox();
			return removeElement;
		}
		/**
		 * @private
		 */
		override protected function resizeBoxModel():void
		{
			// check whether need to relocate elements
			var gap:int = drawStyle.gap[_config.HD];
			if(_gap != gap)
			{
				_gap = gap;
				updateAlignment();
			}
			super.resizeBoxModel();
		}
		/**
		 * Update alignment start from the specified index of element.
		 * @param index The index at which position to align.
		 */
		public function updateAlignment(index:int = 0):void
		{
			var X:String = _config.X;
			var W:String = _config.W;
			var Y:String = _config.Y;
			
			var position:Rectangle = new Rectangle;
			var element:DisplayObject;
			var prevIndex:int = index - 1;
			// get previous position
			if(prevIndex > -1)
			{
				element = elements.getChildAt(prevIndex);
				position[X] = element[X];
				position[W] = element[W];
			}
			else
			{
				position[X] = -_gap;
				position[W] = 0;
			}
			// get element position of index
			for(var len:int = numElements;index < len;++index)
			{
				element = elements.getChildAt(index);
				position[X] = _gap + position[X] + position[W];
				position[W] = element[W];
				element[Y]  = 0;
				element[X]  = position[X];
			}
		}
	}
}
class CONFIG
{
	/**
	 * X-coordinate.
	 */
	public var X:String;
	/**
	 * Width.
	 */
	public var W:String;
	/**
	 * Y-coordinate.
	 */
	public var Y:String;
	/**
	 * Horizontal direction.
	 */
	public var HD:String;
}